package com.lsp.concurrent;

import com.lsp.concurrent.locks.LSPCondition;
import com.lsp.concurrent.locks.LSPReentrantLock;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
@Slf4j
public class ArrayListBlockingQueue<E> {

    private List<E> items;

    private int size;

    private int initialCapacity;

    private LSPReentrantLock lock;

    private final LSPCondition notEmpty;

    private final LSPCondition notFull;


    public ArrayListBlockingQueue(int capacity) {
        if(capacity <= 0)
            throw new IllegalArgumentException();
        this.initialCapacity = capacity;
        this.items = new ArrayList<E>(capacity);
        this.lock = new LSPReentrantLock();
        this.notEmpty = lock.newCondition();
        this.notFull = lock.newCondition();
    }

    private void enqueue(E x) {
        ++size;
        items.add(x);
        notEmpty.signal();
    }

    private E dequeue() {
        --size;
        E e = items.remove(0);
        notFull.signal();
        return e;
    }

    public void put(E e) throws InterruptedException {
        final LSPReentrantLock lock = this.lock;
        lock.lock();
        try {
            while (size == initialCapacity){
                log.info("队列满了，要先等一会儿！");
               notFull.await();
            }
            enqueue(e);
        }finally {
            lock.unlock();
        }
    }

    public E take() throws InterruptedException {
        final LSPReentrantLock lock = this.lock;
        lock.lock();
        try {
            while (size == 0){
                log.info("队列为空，要先等一会儿！");
                notEmpty.await();
            }
            return dequeue();
        }finally {
            lock.unlock();
        }

    }




}
